#include "propeditdialog.h"
#include "ui_propeditdialog.h"
#include "scripteditdialog.h"
#include "mainwindow.h"
#include "propcoordinatedialog.h"
#include <QFileDialog>
#include <QDebug>

PropEditDialog::PropEditDialog(QWidget *parent, PropData *propToEdit) :
    QDialog(parent),
    ui(new Ui::PropEditDialog)
{
    ui->setupUi(this);
    window()->layout()->setSizeConstraint(QLayout::SetFixedSize);
    ui->errorLabel->setText("");

    remMedia = new QAction(this);
    remMedia->setEnabled(false);
    remMedia->setShortcut(Qt::Key_Delete);
    connect(remMedia, SIGNAL(triggered()), this, SLOT(on_mediaRemovePushButton_clicked()));

    setTabOrder(ui->propNameLineEdit, ui->mainAudioPushButton);
    setTabOrder(ui->mainAudioPushButton, ui->p1LatDoubleSpinBox);
    setTabOrder(ui->p1LatDoubleSpinBox, ui->p1LonDoubleSpinBox);
    setTabOrder(ui->p1LonDoubleSpinBox, ui->p1AltDoubleSpinBox);
    setTabOrder(ui->p1AltDoubleSpinBox, ui->p1RadDoubleSpinBox);

    // just disabling for now, may need later
    ui->mainAudioLabel->hide();
    ui->mainAudioLineEdit->hide();
    ui->mainAudioPushButton->hide();
    ui->removeMainAudToolButton->hide();
    ui->scriptEditToolButton->hide();
    ui->p1AltDoubleSpinBox->hide();
    ui->p1RadDoubleSpinBox->setValue(0.000003);
    ui->p1RadDoubleSpinBox->hide();
    ui->label->hide();
    ui->label_2->hide();

    if (propToEdit != 0)
    {
        prop = propToEdit;
        editPropName = propToEdit->getPropName();
        ui->propNameLineEdit->setText(propToEdit->getPropName());
        if (propToEdit->audMain == "")
        {
            ui->mainAudioLineEdit->setText(propToEdit->audMainDevice);
        }
        else
        {
            ui->mainAudioLineEdit->setText(propToEdit->audMain);
        }
        ui->p1LatDoubleSpinBox->setValue(propToEdit->propCoords[0].latitude);
        ui->p1LonDoubleSpinBox->setValue(propToEdit->propCoords[0].longitude);
        ui->p1AltDoubleSpinBox->setValue(propToEdit->propCoords[0].altitude);
        ui->p1RadDoubleSpinBox->setValue(propToEdit->propCoords[0].radius);
        for (unsigned int k = 0; k < propToEdit->aud.size(); k++)
        {
            if (propToEdit->aud[k]->first == "")
            {
                new QListWidgetItem(propToEdit->aud[k]->second, ui->mediaListWidget, AUDIO);
            }
            else
            {
                new QListWidgetItem(propToEdit->aud[k]->first, ui->mediaListWidget, AUDIO);
            }
        }
        for (unsigned int k = 0; k < propToEdit->vid.size(); k++)
        {
            if (propToEdit->vid[k]->first == "")
            {
                new QListWidgetItem(propToEdit->vid[k]->second, ui->mediaListWidget, VIDEO);
            }
            else
            {
                new QListWidgetItem(propToEdit->vid[k]->first, ui->mediaListWidget, VIDEO);
            }
        }
        for (unsigned int k = 0; k < propToEdit->pic.size(); k++)
        {
            if (propToEdit->pic[k]->first == "")
            {
                new QListWidgetItem(propToEdit->pic[k]->second, ui->mediaListWidget, PICTURE);
            }
            else
            {
                new QListWidgetItem(propToEdit->pic[k]->first, ui->mediaListWidget, PICTURE);
            }
        }

        saveOldProp(prop);
    }
    else
    {
        prop = new PropData();
        oldProp = NULL;
    }
    ui->propNameLineEdit->setFocus();
}

PropEditDialog::~PropEditDialog()
{
    delete ui;
}

// Called when the user presses 'ok'
void PropEditDialog::accept()
{
    // If the prop name is invalid, highlight the field and do not continue
    if (!on_propNameLineEdit_lostFocus())
        return;
    // Otherwise, gather data, pass it to MainWindow, and close the dialog
    prop->setAudMain(ui->mainAudioLineEdit->text());
    prop->propCoords[0].latitude = ui->p1LatDoubleSpinBox->value();
    prop->propCoords[0].longitude = ui->p1LonDoubleSpinBox->value();
    prop->propCoords[0].altitude = ui->p1AltDoubleSpinBox->value();
    prop->propCoords[0].radius = ui->p1RadDoubleSpinBox->value();
    // TODO: only set this if the coords actually change
    prop->propStatus = PROP_NOT_SAVED;

    std::vector<QString> aud, vid, pic;
    for (int k = 0; k < ui->mediaListWidget->count(); k++)
    {
        QListWidgetItem *curItem = ui->mediaListWidget->item(k);
        if (curItem->type() == AUDIO)
        {
            aud.push_back(curItem->text());
        }
        else if (curItem->type() == VIDEO)
        {
            vid.push_back(curItem->text());
        }
        else if (curItem->type() == PICTURE)
        {
            pic.push_back(curItem->text());
        }
    }
    prop->addAud(aud);
    prop->addVid(vid);
    prop->addPic(pic);
    prop->changePropName(ui->propNameLineEdit->text());

    emit newPropInfo(prop);
    QDialog::accept();
}

// Browse for main audio to add
void PropEditDialog::on_mainAudioPushButton_clicked()
{
    QString fname = QFileDialog::getOpenFileName(this, "Open audio", QString(), "Audio (*.mp3 *.aac *.m4a *.mp4 *.3gp *.flac *.ogg *.mkv *.mid)");
    ui->mainAudioLineEdit->setText(fname);
}

// Checks if a prop name has been input. If the field is null, highlight it, otherwise, remove any highlight.
// Also replace all '/' and '\' with '-' to avoid issues when creating folders
// Return vals: if text is null, false; otherwise true.
bool PropEditDialog::on_propNameLineEdit_lostFocus()
{
    if (ui->propNameLineEdit->text() == "")
    {
        QPalette pal(ui->propNameLineEdit->palette());
        pal.setColor(QPalette::Base, Qt::yellow);
        ui->propNameLineEdit->setPalette(pal);
        ui->errorLabel->setText("");
        return false;
    }
    else
    {
        QString text = ui->propNameLineEdit->text();
        // illegal chars in windows
        text.replace('/', '-');
        text.replace('\\', '-');
        text.replace(':', '-');
        text.replace('*', '-');
        text.replace('?', '-');
        text.replace('\"', '-');
        text.replace('<', '-');
        text.replace('>', '-');
        text.replace('|', '-');
        text = text.trimmed();
        ui->propNameLineEdit->setText(text);
        if ((text != editPropName && ((MainWindow *)parent())->propExists(text)) || text.toLower() == "minimap")
        {
            QPalette pal(ui->propNameLineEdit->palette());
            pal.setColor(QPalette::Base, Qt::yellow);
            ui->propNameLineEdit->setPalette(pal);
            ui->errorLabel->setText("<b><font color=\"#ff0000\">Prop name already in use!</font></b>");
            return false;
        }
        else
        {
            QPalette pal;
            ui->propNameLineEdit->setPalette(pal);
            ui->errorLabel->setText("");
            return true;
        }
    }
}

// Browse for audio to add
void PropEditDialog::on_audioAddPushButton_clicked()
{
    addMediaToList(QFileDialog::getOpenFileNames(this, "Open audio", QString(), "Audio (*.mp3 *.aac *.m4a *.mp4 *.3gp *.flac *.ogg *.mkv *.mid)"), AUDIO);
}

// Browse for videos to add
void PropEditDialog::on_videoAddPushButton_clicked()
{
    addMediaToList(QFileDialog::getOpenFileNames(this, "Open video", QString(), "Video (*.mp4 *.3gp *.mkv *.webm *.ts)"), VIDEO);
}

// Browse for pictures to add
void PropEditDialog::on_picAddPushButton_clicked()
{
    addMediaToList(QFileDialog::getOpenFileNames(this, "Open Picture", QString(), "Image (*.jpg *.png *.gif *.webp)"), PICTURE);
}

// Add audio/videos/pictures to the media list
// fnames - paths to files
// type - AUDIO, VIDEO, or PICTURE
void PropEditDialog::addMediaToList(QStringList fnames, MediaType type)
{
    QStringList list = fnames;
    QStringList::Iterator it = list.begin();
    while (it != list.end())
    {
        new QListWidgetItem(*it, ui->mediaListWidget, type);
        it++;
    }
}

// Remove all selected media from the list
void PropEditDialog::on_mediaRemovePushButton_clicked()
{
    QList<QListWidgetItem *> toRemove = ui->mediaListWidget->selectedItems();

    while (toRemove.size() > 0)
    {
        QListWidgetItem *tmpItem = toRemove[0];
        ui->mediaListWidget->removeItemWidget(tmpItem);
        toRemove.removeFirst();
        delete tmpItem;
    }
}

// Enable/disable media remove button depending on current selection
void PropEditDialog::on_mediaListWidget_itemSelectionChanged()
{
    if (ui->mediaListWidget->selectedItems().size() > 0)
    {
        ui->mediaRemovePushButton->setEnabled(true);
        remMedia->setEnabled(true);
    }
    else
    {
        ui->mediaRemovePushButton->setEnabled(false);
        remMedia->setEnabled(false);
    }
}

void PropEditDialog::on_removeMainAudToolButton_clicked()
{
    ui->mainAudioLineEdit->setText("");
}

void PropEditDialog::on_scriptEditToolButton_clicked()
{
    ScriptEditDialog scr(prop->audMainScript->first);
    connect(&scr, SIGNAL(scriptUpdate(QString)), this, SLOT(mainAudScriptUpdate(QString)));
    scr.exec();
}

void PropEditDialog::mainAudScriptUpdate(QString text)
{
    prop->setAudMainScript(text);
}

void PropEditDialog::saveOldProp(PropData *prop)
{
    //oldProp = new PropData(prop);
}

void PropEditDialog::on_coordSelPushButton_clicked()
{
    PropCoordinateDialog pcd(((MainWindow *)parent())->getMinimapData(), ui->p1LatDoubleSpinBox->value(), ui->p1LonDoubleSpinBox->value());
    connect(&pcd, SIGNAL(newLatLon(double,double)), this, SLOT(setNewLatLon(double,double)));
    pcd.exec();
}

void PropEditDialog::setNewLatLon(double lat, double lon)
{
    ui->p1LatDoubleSpinBox->setValue(lat);
    ui->p1LonDoubleSpinBox->setValue(lon);
}
